<!-- 异常处理弹层 -->
<script>
import ComAreaMatch from './ComAreaMatch';
import ComHshMatch from './ComHshMatch';
import ComImgWaterMark from './ComImgWaterMark';
import ComVerify from './ComVerify';
import ComHouseAssets from './ComHouseAssets';
import ComIndoorAssets from './ComIndoorAssets';
import ComHouseRecommend from './ComHouseRecommend';
import ComBaseInfoMiss from './ComBaseInfoMiss';
import ComPortInfo from './ComPortInfo';
import ComWaterMark from './ComWaterMark';
import TabImg from './tabs/TabImg';
import TabVideo from './tabs/TabVideo';
import TabVr from './tabs/TabVr';

import { mapActions, mapGetters, mapState } from 'vuex';
import {
  examineDelPushAble,
  examineResblockException,
  getException,
  queryPmReferenceDetailInfoByRefCode,
} from '@/api/user';
import { forceHouseInfoHanlder } from '@/config/house/houseDetailConfig';
import { checkPortAccountHandler, getPushAblePortList } from '@/handler/menuHandler';
import { CODE_MAP, EDIT_TABS, EVENT_PLATFORM_RESBLOCKID, RESOURCE_TABS } from './config';

/** 所有的异常配置 */
let EXCEPTION_TABS;

export default {
  name: 'ComExceptionPop',
  components: {
    ComAreaMatch,
    ComHshMatch,
    ComImgWaterMark,
    ComVerify,
    ComHouseAssets,
    ComIndoorAssets,
    ComHouseRecommend,
    ComBaseInfoMiss,
    ComPortInfo,
    ComWaterMark,
    TabImg,
    TabVideo,
    TabVr,
  },
  props: {
    delId: String,
    excVisible: Boolean,
    type: String, // 'edit': 修改, 'exception': 处理异常  'resource'图片视频vr 
    tab: String, //【 TAB_VR TAB_IMG TAB_VIDEO定位用】
    // success可发列表 fail不可发列表
    from: String,
  },
  data() {
    this.leftIcon = require('@/assets/images/icons/btn-l.png');
    this.rightIcon = require('@/assets/images/icons/btn-r.png');
    return {
      dialogVisible: true,
      tabs: [],
      houseType: '',
      loading: false,
      title: '',
      resblockName: '',
      noPortAccount: null,
      pushAbleAccounts: [], //可发端口列表
      exceptionList: [], //异常列表
    };
  },
  async created() {
    this.$bus.$on(EVENT_PLATFORM_RESBLOCKID, this.resblockChange);
    this.$once('hook:beforeDestroy', () => {
      this.$bus.$off(EVENT_PLATFORM_RESBLOCKID);
    });

    this.loading = true;
    await this.initTabs();

    this.loading = false;

    const { tabs, tab } = this
    if (tabs.length) {
      if (tab) {
        const item = tabs.find((v) => v.tab === tab)
        this.houseType = (item && item.value) || tabs[0].value;
      } else {
        this.houseType = tabs[0].value;
      }
    }
  },
  mounted() { },
  watch: {},
  computed: {
    ...mapState({
      info: (state) => state.houseInfo,
      hmDelSummaryInfo: (state) => state.houseInfo.hmDelSummaryInfo,
      houDelVO: (state) => state.houseInfo.houDelVO,
      houPortInfo: (state) => state.houseInfo.houPortInfo,
    }),
    curIndex() {
      return this.tabs.findIndex((v) => v.value == this.houseType);
    },
    saveAble({ houDelVO }) {
      return forceHouseInfoHanlder(houDelVO);
    },
    ...mapGetters({
      indoorList: 'houseInfo/indoorList'
    }),
  },
  methods: {
    ...mapActions({
      updateInfoById: 'houseInfo/updateInfoById',
    }),

    async initAccounts() {
      try {
        let accounts = await checkPortAccountHandler();
        this.pushAbleAccounts = accounts;
        this.noPortAccount = 1;
      } catch (code) {
        this.noPortAccount = code;
      }
    },

    async initTabs() {
      await this.initAccounts();

      // 更新房源信息
      const { houDelVO } = await this.updateInfoById(this.delId);
      this.resblockName = houDelVO.resblockName;

      if (!EXCEPTION_TABS) {
        EXCEPTION_TABS = await this.getConfigTabs();
      }

      let { type, from } = this;

      if (type == 'edit') {
        if (from === 'fail' && this.noPortAccount == 1) {
          await this.resblockUnMatched(this.delId);
        }
        this.tabs = EDIT_TABS;
        this.title = '房源修改';
      } else if (type == 'exception') {
        this.title = '房源异常处理';

        const portType = await getPushAblePortList();
        let { content } = await getException({ delId: this.delId, portType });

        content = content.reduce((res, item) => {
          const ex = res[item.exceptionType];
          res[item.exceptionType] = ex ? [...ex, item] : [item];
          return res;
        }, {});

        this.tabs = Object.keys(content).map((item) => {
          const tab = EXCEPTION_TABS.find((v) => v.value === item);
          tab.portList = content[item];
          return tab;
        });
      } else if (type == 'resource') {
        this.title = '房源素材';
        this.tabs = JSON.parse(JSON.stringify(RESOURCE_TABS));

        this.updateLabels()
      }
    },

    updateLabels() {
      const update = (tabName, v) => {
        const tab = this.tabs.find((v) => v.componentName == tabName)
        const i = tab.label.indexOf('(')
        const label = i > -1 ? tab.label.slice(0, i) : tab.label
        tab.label = `${label}(${v})`
      }

      update('TabImg', this.indoorList.length)
      const { houSubType, houSubTypeState, videoMaterial } = this.hmDelSummaryInfo
      update('TabVr', (houSubType == 1 && houSubTypeState == 10) ? 1 : 0)
      update('TabVideo', (videoMaterial && videoMaterial.videoId) ? 1 : 0)
    },

    // 查询该小区的所有异常信息
    async resblockUnMatched(delId) {
      const portTypeList = await getPushAblePortList();
      let { content } = await getException({ delId, portType: portTypeList });

      this.exceptionList = content;
    },

    resblockChange(id, name, portType) {
      // return console.log('校验户室号异常', {id, name, portType});

      this.loading = true;
      examineResblockException({
        portType,
        delId: this.delId,
        platformResblockId: id,
        platformResblockName: name,
      })
        .then((content) => {
          const port = this.houPortInfo.find((v) => v.portType == portType);
          if (!port) throw new Error('portType error');
          port.platformResblockId = id;
          port.portResblockName = name;

          const exitIndex = this.tabs.findIndex((v) => v.value == 'hushihao');
          // 户室号有异常
          if (Array.isArray(content) && content[0] == 'hushihao') {
            if (exitIndex > -1) return;

            const tabItem = EXCEPTION_TABS.find((v) => v.value == 'hushihao');
            const index = this.tabs.findIndex((v) => v.value == 'resBlockId');
            // 保证顺序（户室号异常跟在小区异常后面）
            this.tabs.splice(index + 1, 0, tabItem);

            // 户室号无异常
          } else {
            if (exitIndex > -1) {
              this.tabs.splice(exitIndex, 1);
            }
            // 只剩小区异常 && 多平台的小区异常匹配全部ok  则直接保存退出弹层
            const resBlockOk = this.houPortInfo.every((v) => !!v.platformResblockId && !!v.portResblockName);
            if (this.tabs.length == 1 && resBlockOk) {
              this.$emit('handleResult', { type: 'success', delId: this.delId });
              this.$emit('change')
              this.hide();
            }
          }
        })
        .finally(() => {
          this.loading = false;
        });
    },

    async getConfigTabs() {
      const { content } = await queryPmReferenceDetailInfoByRefCode({ refCode: 'hmDelException' });
      return content
        .map((item) => {
          return {
            label: item.refDetailName,
            value: item.refDetailCode,
            componentName: CODE_MAP[item.refDetailCode],
          };
        })
        .filter((v) => !!v.componentName);
    },
    hideBefore() {
      const components = this.getChildrenComponents();
      const modified = components.some((c) => c.modifiedCount <= 0);
      if (modified) {
        this.$messageBox
          .confirm('是否确认放弃您之前的修改？', {
            title: '系统提示：',
            confirmButtonText: '确认放弃',
            cancelButtonText: '返回',
          })
          .then(() => {
            this.hide();
          });
      } else {
        this.hide();
      }
    },
    getChildrenComponents() {
      const components = [];
      const bc = (children) => {
        children.map((c) => {
          if (c.$options.shulan && c.save) {
            components.push(c);
          }
          if (c.$children) {
            bc(c.$children);
          }
        });
      };
      bc(this.$children);

      return components;
    },
    async confirm() {
      this.loading = true;

      const components = this.getChildrenComponents();
      try {
        for (let i = 0; i < components.length; i++) {
          await components[i].save();
        }
        await examineDelPushAble({ delId: this.delId });

        // 判断是否任然存在异常
        if (this.type == 'exception') {
          const portType = await getPushAblePortList();
          let { content } = await getException({ delId: this.delId, portType });
          this.$emit('handleResult', { type: content.length ? 'error' : 'success', delId: this.delId });
        } else {
          this.$message.success('保存成功！');
        }

        this.$emit('change')
        this.hide();
      } catch ({ errorMessage }) {
        this.$message.error(errorMessage);
        await examineDelPushAble({ delId: this.delId });
      }

      this.loading = false;
    },

    handleSwitchover(num) {
      let i = this.tabs.findIndex((v) => v.value == this.houseType) + num;
      i = Math.max(Math.min(i, this.tabs.length - 1), 0);
      this.houseType = this.tabs[i].value;
    },

    updateTabNames(componentName, value) {
      // this.updateLabels()
    },
    hideBefore() {
      const components = this.getChildrenComponents();
      const modified = components.some((c) => c.modifiedCount <= 0);
      if (modified) {
        this.$messageBox
          .confirm('是否确认放弃您之前的修改？', {
            title: '系统提示：',
            confirmButtonText: '确认放弃',
            cancelButtonText: '返回',
          })
          .then(() => {
            this.hide();
          });
      } else {
        this.hide();
      }
    },
    hide() {
      this.$emit('update:excVisible', false);
    },
  },
  render(h) {
    const {
      dialogVisible,
      tabs,
      loading,
      title,
      curIndex,
      saveAble,
      noPortAccount,
      pushAbleAccounts,
      from,
      type,
      exceptionList,
      updateTabNames,
    } = this;
    const domTabs = tabs.map((item) => {
      const props = { type, from, exceptionList, noPortAccount, pushAbleAccounts, portList: item.portList };
      const events = { updateTabNames }
      return (
        <el-tab-pane key={item.label} label={item.label} name={item.value}>
          {h(item.componentName, { props, on: events })}
        </el-tab-pane>
      );
    });

    return (
      <el-dialog
        width="1100px"
        visible={dialogVisible}
        on={{ 'update:visible': this.hideBefore }}
        v-loading={loading}
        element-loading-background="rgba(0, 0, 0, 0.8)"
        append-to-body
        close-on-click-modal={false}
        top="8vh"
        class="dialog"
      >
        <el-tabs v-model={this.houseType}>{domTabs}</el-tabs>
        {curIndex > 0 ? (
          <img src={this.leftIcon} class="btn-left btn" onClick={this.handleSwitchover.bind(this, -1)} />
        ) : null}
        {curIndex < tabs.length - 1 ? (
          <img src={this.rightIcon} class="btn-right btn" onClick={this.handleSwitchover.bind(this, 1)} />
        ) : null}
        <div class="title" slot="title">
          {title}
        </div>
        <span slot="footer">
          <el-button onClick={this.hideBefore}>取 消</el-button>
          <el-button type="primary" disabled={!saveAble} onClick={this.confirm}>
            保 存
          </el-button>
        </span>
      </el-dialog>
    );
  },
};
</script>
<style lang="scss" scoped>
.el-tabs /deep/ .el-tabs__content {
  overflow: visible;
}
.btn {
  width: 80px;
  height: 200px;
  position: absolute;
  top: 50%;
  transform: translateY(-50%);
  cursor: pointer;
}
.btn-left {
  left: -80px;
}
.btn-right {
  right: -80px;
}
.title {
  color: #333333;
  font-size: 26px;
  font-weight: bold;
}
.dialog /deep/ .el-dialog__body {
  padding-top: 0;
  min-height: 620px;
}
</style>
